﻿// 方向重力操作区
function Operation() {
	this.canrun = false;	// 不允许重力感应操作
	var me = this;

	var originX = 0, originY = 0, currrentX = 0, currentY = 0;

	//提示
	//var domAlpha = document.getElementById('alpha');
	//var domBeta = document.getElementById('beta');
	//var domGamma = document.getElementById('gamma');

	// 画布
	var canvas = document.getElementById('operation');
	canvas.onclick = function () {
		me.canrun = !me.canrun;
		if (me.canrun) {
			originY = currentY;	// 把当前的设备角度设为原点
			originX = currentX;
		}
		autopilot.pause2();	// 停止自动操作
		render.stop();
	}
	var ww = canvas.clientWidth;		// 绘图区宽
	var hh = canvas.clientHeight;		// 绘图区高
	var ctxOperation = canvas.getContext('2d'); // 绘图环境
	ctxOperation.strokeStyle = "#c0e07d";
	ctxOperation.lineWidth = 1;

	function draw(ex, ey) {
		ctxOperation.clearRect(0, 0, ww, hh);
		//画控制面板
		// 画井
		var x = 0;
		var y = 0;
		ctxOperation.beginPath();
		for (var i = 0; i < 4; i++) {
			ctxOperation.moveTo(0, y);	// 横线
			ctxOperation.lineTo(ww, y);
			y += hh / 3;
			ctxOperation.moveTo(x, 0);	// 竖线
			ctxOperation.lineTo(x, hh);
			x += ww / 3;
		}
		ctxOperation.stroke();		// 描边

		var x = ww / 2 + ex * ww / 30;	// 限制在框内，最后一个数调整灵敏度
		var y = hh / 2 - ey * hh / 30;
		x = x < ww ? x < 0 ? 0 : x : ww;
		y = y < hh ? y < 0 ? 0 : y : hh;

		var w2 = 8;		// 直箭头尺寸，杆半宽
		var w3 = w2 * 2;	// 杆全宽
		var w4 = w2 * 0.7;	// 斜箭头尺寸
		var w5 = w4 * 2;

		if (!me.canrun) {	// 如果不能动，画个方块。
			ctxOperation.closePath();
			ctxOperation.fillStyle = "#cccccc";
			ctxOperation.fillRect(x - w5, y - w5, w5 * 2, w5 * 2);
			return;
		}

		var tu = x < ww / 1.5 ? x < ww / 3 ? -radianframe : 0 : radianframe;  // 转向
		var sp = y < hh / 1.5 ? y < hh / 3 ? speed1 : 0 : -speed1;   // 速度
		car.turn0 = (x < ww / 1.5 && x > ww / 3 && (y > hh / 1.5 || y < hh / 3)); // 回正方向
		//domAlpha.innerHTML = (x > (ww / 1.667));

		if (tu !== car.turn || sp !== car.speed) {
			car.turn = tu;
			car.speed = sp;
			if (car.speed !== 0 || car.turn !== 0)
				render.start();
			else
				render.stop();
		}

		// 浮动圆点
		ctxOperation.beginPath();
		ctxOperation.fillStyle = "#c0e07d";
		if (car.speed > 0) {
			if (car.turn > 0) {	// 右上
				ctxOperation.moveTo(x - w4, y - w4);
				ctxOperation.lineTo(x - w5, y - w5);
				ctxOperation.lineTo(x + w5, y - w5);
				ctxOperation.lineTo(x + w5, y + w5);
				ctxOperation.lineTo(x + w4, y + w4);
				ctxOperation.lineTo(x + w4 - w5, y + w4 + w5);
				ctxOperation.lineTo(x - w4 - w5, y - w4 + w5);
				ctxOperation.closePath();
			}
			else if (car.turn < 0) {	// 左上
				ctxOperation.moveTo(x + w4, y - w4);
				ctxOperation.lineTo(x + w5, y - w5);
				ctxOperation.lineTo(x - w5, y - w5);
				ctxOperation.lineTo(x - w5, y + w5);
				ctxOperation.lineTo(x - w4, y + w4);
				ctxOperation.lineTo(x - w4 + w5, y + w4 + w5);
				ctxOperation.lineTo(x + w4 + w5, y - w4 + w5);
				ctxOperation.closePath();
			}
			else {	// 上
				ctxOperation.moveTo(x - w2, y);
				ctxOperation.lineTo(x - w3, y);
				ctxOperation.lineTo(x, y - w3);
				ctxOperation.lineTo(x + w3, y);
				ctxOperation.lineTo(x + w2, y);
				ctxOperation.lineTo(x + w2, y + w3);
				ctxOperation.lineTo(x - w2, y + w3);
				ctxOperation.closePath();
			}
		}
		else if (car.speed < 0) {
			if (car.turn > 0) {	// 右下
				ctxOperation.moveTo(x - w4, y + w4);
				ctxOperation.lineTo(x - w5, y + w5);
				ctxOperation.lineTo(x + w5, y + w5);
				ctxOperation.lineTo(x + w5, y - w5);
				ctxOperation.lineTo(x + w4, y - w4);
				ctxOperation.lineTo(x + w4 - w5, y - w4 - w5);
				ctxOperation.lineTo(x - w4 - w5, y + w4 - w5);
				ctxOperation.closePath();
			}
			else if (car.turn < 0) {	// 左下
				ctxOperation.moveTo(x + w4, y + w4);
				ctxOperation.lineTo(x + w5, y + w5);
				ctxOperation.lineTo(x - w5, y + w5);
				ctxOperation.lineTo(x - w5, y - w5);
				ctxOperation.lineTo(x - w4, y - w4);
				ctxOperation.lineTo(x - w4 + w5, y - w4 - w5);
				ctxOperation.lineTo(x + w4 + w5, y + w4 - w5);
				ctxOperation.closePath();
			}
			else {	// 下
				ctxOperation.moveTo(x - w2, y);
				ctxOperation.lineTo(x - w3, y);
				ctxOperation.lineTo(x, y + w3);
				ctxOperation.lineTo(x + w3, y);
				ctxOperation.lineTo(x + w2, y);
				ctxOperation.lineTo(x + w2, y - w3);
				ctxOperation.lineTo(x - w2, y - w3);
				ctxOperation.closePath();
			}
		}
		else {
			if (car.turn > 0) {	// 右
				ctxOperation.moveTo(x, y - w2);
				ctxOperation.lineTo(x, y - w3);
				ctxOperation.lineTo(x + w3, y);
				ctxOperation.lineTo(x, y + w3);
				ctxOperation.lineTo(x, y + w2);
				ctxOperation.lineTo(x - w3, y + w2);
				ctxOperation.lineTo(x - w3, y - w2);
				ctxOperation.closePath();
			}
			else if (car.turn < 0) {	// 左
				ctxOperation.moveTo(x, y - w2);
				ctxOperation.lineTo(x, y - w3);
				ctxOperation.lineTo(x - w3, y);
				ctxOperation.lineTo(x, y + w3);
				ctxOperation.lineTo(x, y + w2);
				ctxOperation.lineTo(x + w3, y + w2);
				ctxOperation.lineTo(x + w3, y - w2);
				ctxOperation.closePath();
			}
			else {	//中
				ctxOperation.fillStyle = "#cccccc";
				ctxOperation.arc(x, y, w5, 0, degree1 * 360, true);	// 实心圆点
			}
		}
		ctxOperation.fill();
	}

	// 方向事件
	window.ondeviceorientation = function (e) {	//http://06wj.blog.163.com/blog/static/834657352012058123053/   //http://www.pjhome.net/article/Javascript/html5_Orientation.html
		// 通过方向事件，用设备角度，不同设备，不同浏览器角度表示方法不一样，正负180度范围内各设备和浏览器一至。
		// 只能横向使用，向前翻前进，向后翻倒车，向左是左转，向右是右转。

		if (window.ondevicemotion) {	// 优先使用方向事件，因为加速度事件会受移动影响
			if (e.beta)
				window.ondevicemotion = undefined;
			else
				window.ondeviceorientation = undefined;

			//alert(window.ondevicemotion);
		}

		var ex = e.beta;	//默认向左横，右转（往右翻）是正，左转（向左翻）是负
		var ey = e.gamma;	//默认向左横，前进（向上翻）是正，后退（向下翻）是负

		// g14 android 自带浏览器，beta范围是-90到270
		// 向左横，从手机左侧看，顺时针方向，水平向上为0点
		// 绝对角度    0    90- 90+    180- 180+    270- 270+    360
		// beta左上    1      1            1            1         1
		// beta左下   -1     -1           -1           -1        -1
		// gamma       0      90          180       270  -90     0
		if (ey > 180)
			ey -= 360;	// 把180到270变成-180到-90

		// chorme浏览器，bata范围是正负90，翻过来时gamma的绝对值在180附近
		// 向左横，从手机左侧看，顺时针方向，水平向上为0点
		// 绝对角度    0    90- 90+    180- 180+    270- 270+    360
		// beta左上    1    1   179       179       179   1       1
		// beta左下   -1   -1  -179      -179      -179  -1      -1
		// gamma       0    90  -90       0   0      90  -90      0
		if (ex < -135 || ex > 135) {
			ey += ey < 0 ? 180 : -180;
			ex = (ex > 135 ? 180 : -180) - ex;;
		}

		// uc浏览器，bata范围是正负90，翻过来时gamma的绝对值在180附近
		// 向左横，从手机左侧看，顺时针方向，水平向上为0点
		// 绝对角度    0    90- 90+    180- 180+    270- 270+    360
		// beta左上    1    1   179       179       179   1       1
		// beta左下   -1   -1  -179      -179      -179  -1      -1
		// gamma       0      90         0   0         -90        0
		/*if (ex < -135 || ex > 135) {
			ey += ey < 0 ? 180 : -180;
			ex = (ex > 135 ? 180 : -180) - ex;;
		}*/

		// 校正左右横屏的数据
		if (window.orientation < 0)	// 向右横屏时把数据反过来
			ex = -ex, ey = -ey;
		else if (window.orientation === 0) {	// 竖屏
			var xx = ey;
			ey = -ex;
			ex = xx;
		}

		//$("#hidecar").html(e.beta.toFixed(0) + "<br>" + e.gamma.toFixed(0) + "<br>" + e.alpha.toFixed(0));

		// 保存当前位置
		currentX = ex;
		currentY = ey;

		// 设置原点，调整到正负180范围内
		ey -= originY;	// 以当前位置为原点
		if (ey > 180)
			ey -= 360;
		else if (ey < -180)
			ey += 360;

		ex -= originX;
		if (ex > 180)
			ex -= 360;
		else if (ex < -180)
			ex += 360;

		draw(ex, ey);
	}

	// 重力加速度事件
	// ondevicemotion事件比ondeviceorientation事件兼容性好 20140420 一个是方向事件，一个是重力事件
	window.ondevicemotion = function (e) {	//http://06wj.blog.163.com/blog/static/834657352012058123053/   //http://www.pjhome.net/article/Javascript/html5_Orientation.html
		// 通过重力事件，用设备角度，不同设备，不同浏览器角度表示方法不一样，正负90度范围内各设备和浏览器一至。
		// 只能横向使用，以45度角为原点，向前翻前进，向后翻倒车，向左是左转，向右是右转。
		var ex = e.accelerationIncludingGravity.y;	// x y 方向互换
		var ey = e.accelerationIncludingGravity.x;
		var ez = e.accelerationIncludingGravity.z;

		// 调整到正负1之间，由于晃动等原因加速度可能大于g
		var g = 9.8;	// 重力速度度
		ex = (ex < g ? ex > -g ? ex / g : -1 : 1);
		ey = ey < g ? ey > -g ? ey / g : -1 : 1;
		ez = ez < g ? ez > -g ? ez / g : -1 : 1;

		// 转换成绕三个轴的角度，区间是0到180度
		var p = 180 / Math.PI;
		ex = Math.acos(ex) * p;
		ey = Math.acos(ey) * p;
		ez = Math.acos(ez) * p;

		// ex方向倾斜时近似计算翻转角度
		var dx = ex > 90 ? ex - 90 : 90 - ex;
		ey = 90 * (ey - dx) / (90 - dx);
		if (ey < 0) ey = 0;
		if (ey > 180) ey = 180;

		// 转换到规定坐标，
		// 水平面状态ex, ey都是零，正负各180度。
		// 右转，左上右下是正，0到180度；左转，右上左下是负0到-180度。
		// 前进，相对于眼睛，上远下近是正，0到180度；后退，下远上近是负，0到-180。
		ex = 90 - ex;
		ey = ez > 90 ? ey > 90 ? 270 - ey : -90 - ey : ey - 90;

		// 校正左右横屏的数据
		if (window.orientation < 0)	// 向右横屏时把数据反过来
			ex = -ex, ey = -ey;

		//$("#hidecar").html(ex.toFixed(0) + " " + ey.toFixed(0) + " " + ez.toFixed() );

		// 保存当前位置
		currentX = ex;
		currentY = ey;

		// 设置原点，调整到正负180范围内
		ey -= originY;	// 以当前位置为原点
		if (ey > 180)
			ey -= 360;
		else if (ey < -180)
			ey += 360;

		ex -= originX;
		if (ex > 180)
			ex -= 360;
		else if (ex < -180)
			ex += 360;

		draw(ex, ey);
	}

	/*window.ondeviceorientation = function (e) {
		alert(e.beta);
		if (e.beta === null)
			window.ondevicemotion = ondevicemotion;	// 这种情况ondeviceorientation只运行一次
		else
			window.ondeviceorientation = ondeviceorientation;
	}*/

}

